package com.youngjun.common.mybatis.web;

import com.youngjun.common.mybatis.page.PageParams;
import com.youngjun.common.mybatis.plugin.PageHelper;
import com.youngjun.common.oss.expection.CommonException;
import com.youngjun.common.pojo.dto.support.PageDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Map;
import java.util.Objects;

/**
 * @author virgojun
 */
public interface BaseController {

    final static Logger logger = LoggerFactory.getLogger(BaseController.class);

    default HttpServletRequest getRequest() {
        return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
    }


    default HttpServletResponse getResponse() {
        return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getResponse();
    }

    default PageParams getPageParams(PageDTO dto) {
        Integer current = dto.getCurrent();
        Integer pageSize = dto.getPageSize();
        String orderBy = dto.getOrderBy();
        return new PageParams(current, pageSize, orderBy);
    }

    default PageParams getPageParams(Map<String, String[]> parameterMap) {
        Integer current = null;
        if (parameterMap.containsKey("current") && parameterMap.get("current").length > 0) {
            try {
                current = Integer.parseInt(parameterMap.get("current")[0]);
            } catch (Exception ignored) {
            }
        }
        Integer pageSize = null;
        if (parameterMap.containsKey("pageSize") && parameterMap.get("pageSize").length > 0) {
            try {
                pageSize = Integer.parseInt(parameterMap.get("pageSize")[0]);
            } catch (Exception ignored) {
            }
        }
        String orderBy = null;
        if (parameterMap.containsKey("orderBy") && parameterMap.get("orderBy").length > 0) {
            orderBy = parameterMap.get("orderBy")[0];
        }
        return new PageParams(current, pageSize, orderBy);
    }

    default PageParams getPageParams() {
        return getPageParams(getRequest().getParameterMap());
    }

    /**
     * 通用异常处理
     *
     * @param exception
     * @return
     */
    @ExceptionHandler()
    default ResponseEntity<Response<Void>> handleException(Exception exception) throws Exception {
        try {
            PageHelper.clearPage();
        } catch (Exception ignored) {

        }
        // 请求参数导致的异常
        if (exception instanceof BindException) {
            return ResponseEntity
                    .status(HttpStatus.BAD_REQUEST)
                    .body(new Response<Void>().exception(exception));
        }
        else if (exception instanceof CommonException) {
            return ResponseEntity
                    .status(HttpStatus.OK)
                    .body(new Response<Void>().exception(exception));
        }
        else {
            // 系统内部导致的异常
            return ResponseEntity
                    .status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(new Response<Void>().exception(exception));
        }
    }

    /**
     * 必须在写入文件流之前调用
     *
     * @param fileName
     */
    default void setDownloadHeaders(String fileName) {
        setDownloadHeaders(fileName, -1);
    }

    /**
     * 必须在写入文件流之前调用
     *
     * @param fileName
     * @param fileLength
     */
    default void setDownloadHeaders(String fileName, long fileLength) {
        HttpServletResponse response = getResponse();
        try {
            fileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        response.setHeader("Content-Disposition", String.format("attachment; filename=%s;filename*=utf-8''%s", fileName, fileName));
        response.setHeader("Content-Type", "application/force-download");
        response.setHeader("Content-Transfer-Encoding", "binary");
        response.setHeader("Content-Length", String.valueOf(fileLength));
    }

}